#include "uploadfile.h"

#define FileHeadCashBufferSize	140
#define PressureDataCount	(9)
#define EveryReadDataByte 1000

uploadFile::uploadFile()
{
}


//初始化所有路径
void uploadFile::upload()  //创建一个dialog对话框，输入上传文件路径和下载文件路径，再直接赋值给workfloder和savewfloder
{

    QSettings settings("floderContent.ini",QSettings::IniFormat);
    printContentChoose = settings.value("section/printContentChoose").toString().toInt();
    WorkFloder = settings.value("section/work_floder").toString();
    SaveFloder = settings.value("section/save_floder").toString();
    qDebug()<<WorkFloder;
    qDebug()<<SaveFloder;
    QSettings settings1("config.ini",QSettings::IniFormat);
    this->token = settings1.value("section/token").toString();
    qDebug()<<"线程这的token字符串为"<<this->token;
    GetGaitDir();    //开始上传下载
}

//获得后缀为Gait文件的路径
void uploadFile::GetGaitDir()
{
    QDir dir(WorkFloder);
    //判断路径是否存在
    if(!dir.exists() || dir.entryInfoList().size() == 0)
    {
        qDebug("该目录不存在！\n");
        return ;
    }

    dir.setFilter(QDir::Files); //实现对文件的过滤
    dir.setSorting(QDir::Name); //实现对文件输出的排序

    QFileInfoList list = dir.entryInfoList();
    QStringList string_list;

    for (int i = 0; i < list.size(); ++i)
    {
        QFileInfo fileInfo = list.at(i);
        QString suffix = fileInfo.suffix();
        //遍历所有后缀为gait的文件获取路径添加到String_list中
        if(QString::compare(suffix,QString("gait"),Qt::CaseInsensitive) ==  0)//通过QFileInfo来实现对文件类型的过滤
        {
            // 获取gait文件的绝对路径
            QString absolute_file_path = fileInfo.absoluteFilePath();
            string_list.append(absolute_file_path);
        }
    }

    if(string_list.size() == 0)
    {
        return;
    }
    //遍历String_list里的路径解析加生成
    for(int i = 0;i<string_list.size();i++)//用迭代器的输出
    {
        qDebug() <<"导入的gait文件："<< string_list[i];
        QString tmpFileName = string_list[i];
        slotExportOriginalDataCSV(tmpFileName);
        generateFileName(tmpFileName);
    }

}

//生成文件名
void uploadFile::generateFileName(QString tmpFileName)
{

    QStringList gait_path = tmpFileName.split("/");
    QString gait = gait_path[gait_path.size()-1];
    QStringList gait_name = gait.split(".");
    QString name = gait_name[0];
    QString userinfo = name + "userinfo.json";
    QString featureData = name + "featureData.json";
    QString cop_rightfoot = name + "cop_rightfoot.json";
    QString cop_leftfoot = name + "cop_leftfoot.json";
    QString rightFoot_csv = name + ".gait_rightFoot.csv";
    QString leftFoot_csv = name + ".gait_leftFoot.csv";
    QStringList file_list;
        QFile userInfoFile(WorkFloder+"/"+userinfo);
        if(!userInfoFile.open(QIODevice::ReadOnly))
           {
               qDebug() << "could't open projects json";
               return;
           }
        QByteArray allData = userInfoFile.readAll();
            userInfoFile.close();
            QJsonParseError jsonError;
                QJsonDocument jsonDoc(QJsonDocument::fromJson(allData, &jsonError));

                if(jsonError.error != QJsonParseError::NoError)
                {
                    qDebug() << "json error!" << jsonError.errorString();
                    return;
                }

                QJsonObject rootObj = jsonDoc.object();
                if(rootObj.contains("name"))
                    {
                          //为上传的压缩文件zip获取文件名
                        UploadZipName = rootObj.value("name").toString();
                }


    file_list<<gait<<userinfo<<featureData<<cop_rightfoot<<cop_leftfoot<<rightFoot_csv<<leftFoot_csv;
     qDebug() <<"生成新文件的列表："<<file_list;
    moveFiletoTempPath(file_list);
}

//移动文件到临时文件夹
void uploadFile::moveFiletoTempPath(QStringList file_list)
{
    QString temppath = "tempPath/";
    QString tempPath = QDir::currentPath()+"/"+temppath;
    QDir dir;
    if(!dir.exists(tempPath))
    {
        dir.mkdir(tempPath);
    }
    int j = 0;
    for(int i = 0; i < file_list.size(); ++i)
    {
        QString oldname = WorkFloder+"/"+file_list[i];
        QFileInfo file(oldname);
        if(!file.exists())
        {
            qDebug()<<"文件缺少";
            return;
        }
    }
    for(int i = 0; i < file_list.size(); ++i)
    {
        QString oldname = WorkFloder+"/"+file_list[i];
        QString newname = tempPath+file_list[i];
         qDebug()<<"文件移动成功,文件的路径为"<<newname;
       if(QFile::rename(oldname,newname)){
           j++;
           if(j >= file_list.size())
           {
                qDebug()<<"文件移动成功,文件的路径为"<<newname;
                break;
           }
       }
    }

    createZipFile(tempPath);
}
//创建zip文件
void uploadFile::createZipFile(QString tempPath)
{
    QDateTime time = QDateTime::currentDateTime();   //获取当前时间
    QString timeT = time.toString("yyyyMMddhhmmss");
    QString zipPath = "exportZip/";
    QString exportZip = QDir::currentPath()+"/"+zipPath;
    QDir dir2;
    if(!dir2.exists(exportZip))
    {
        dir2.mkdir(exportZip);
    }
    exportZip.append(timeT);
    exportZip.append(".zip");
    QDir dir(tempPath);
        qDebug()<<"tempPath="<<tempPath<<endl<<"exportZip="<<exportZip;
    if(JlCompress::compressDir(exportZip,tempPath)){
        qDebug()<<"压缩完成,压缩路径为"<<exportZip;
        //清空临时文件夹
        dir.setFilter(QDir::Files);
        int fileCount = dir.count();
        for (int i = 0; i < fileCount; i++)
        {
            dir.remove(dir[i]);
        }
        //上传压缩包
        uploadFiles(exportZip);
//        QFile::remove(exportZip);//删除上传的zip文件
    }
}

//解析CSV
void uploadFile::slotExportOriginalDataCSV(QString tmpFileName)
{
    QFile file(tmpFileName);//打开文件
        bool bRet = file.open(QIODevice::ReadOnly);
        if (!bRet)
        {
            qDebug()<<"打开文件失败！"<<endl;
            return;
        }

        std::vector<FSFrameData>	tmpVectorCashData;//存放读取的文件
           std::vector<FSFrameData>	l_data;//解析成功以后的左脚数据
           std::vector<FSFrameData>	r_data;//解析成功以后的右脚数据

           int everyReadCashDataCount = EveryReadDataByte / 105;//每次1000字节 共几次
           qint64 everyReadByte = everyReadCashDataCount * 105;  //几次共多少字节 不大于1000
           char tmpBuffer[EveryReadDataByte];
           qint64 readByte = file.read(tmpBuffer, 140);
           readByte = file.read(tmpBuffer, everyReadByte);
           while (readByte == everyReadByte)
           {
                   //解析数据
               for (int i = 0; i < everyReadCashDataCount; i++)
               {
                   FSFrameData tmpFSFrameData;
                   memcpy(&tmpFSFrameData, &tmpBuffer[i * 105], 105);
                   tmpVectorCashData.push_back(tmpFSFrameData);
               }

               readByte = file.read(tmpBuffer, everyReadByte);//再次从文件中读取数据
           }

           qint64 residueCount = readByte / 105;
           for (qint64 i = 0; i < residueCount; i++)
               {
                   FSFrameData tmpFSFrameData;
                   memcpy(&tmpFSFrameData, &tmpBuffer[i*105], 105);
                   tmpVectorCashData.push_back(tmpFSFrameData);
               }

               for (unsigned long long i = 0; i < tmpVectorCashData.size(); i++)
               {
                   if (tmpVectorCashData[i].index == NodeSuitIDLeftFoot)
                   {
                       l_data.push_back(tmpVectorCashData[i]);
                   }
                   else if (tmpVectorCashData[i].index == NodeSuitIDRightFoot)
                   {
                       r_data.push_back(tmpVectorCashData[i]);
                   }
               }
               QFile l_csv(tmpFileName +"_leftFoot.csv");
                 if(l_csv.open(QFile::WriteOnly | QFile::Truncate))        // 打开文件
                 {
                     QTextStream outFile(&l_csv);    // 输入流
                     outFile << "l_time" << ',' << "l_Pressure1" << ',' << "l_Pressure2" << ',' << "l_Pressure3"
                             << ',' << "l_Pressure4" << ',' << "l_Pressure5"<<',' << "l_Pressure6" << ',' << "l_Pressure7"
                             << ',' << "l_Pressure8"<< ',' << "l_Pressure9" << ',' << "l_Quat_w" << ',' << "l_Quat_x" << ','
                             << "l_Quat_y" << ',' << "l_Quat_z" << ',' << "l_Accel_x" << ',' << "l_Accel_y" << ',' << "l_Accel_z"
                             << ',' << "l_Gyro_x" << ',' << "l_Gyro_y" << ',' << "l_Gyro_z"<< endl;

                     for (unsigned long long i = 0; i<l_data.size(); i++)
                     {
                         outFile << l_data[i].time << ',' << l_data[i].pressure[0] << ','
                                 << l_data[i].pressure[1] << ',' << l_data[i].pressure[2]
                                 << ',' << l_data[i].pressure[3] << ',' << l_data[i].pressure[4]
                                 << ',' << l_data[i].pressure[5] << ',' << l_data[i].pressure[6]
                                 << ',' << l_data[i].pressure[7] << ',' << l_data[i].pressure[8]
                                 << ',' << l_data[i].quat[0] << ',' << l_data[i].quat[1]
                                 << ',' << l_data[i].quat[2] << ',' << l_data[i].quat[3]
                                 << ',' << l_data[i].accel[0] << ',' << l_data[i].accel[1]
                                 << ',' << l_data[i].accel[2] << ',' << l_data[i].gyro[0]
                                 << ',' << l_data[i].gyro[1] << ',' << l_data[i].gyro[2] << endl;
                     }
                 }

                 l_csv.close();

                    QFile r_csv(tmpFileName +"_rightFoot.csv");
                    if(r_csv.open(QFile::WriteOnly | QFile::Truncate))        // 打开文件
                    {
                        QTextStream outFile(&r_csv);    // 输入流
                        outFile << "r_time" << ',' << "r_Pressure1" << ',' << "r_Pressure2" << ',' << "r_Pressure3"
                                << ',' << "r_Pressure4" << ',' << "r_Pressure5"<<',' << "r_Pressure6" << ',' << "r_Pressure7"
                                << ',' << "r_Pressure8"<< ',' << "r_Pressure9" << ',' << "r_Quat_w" << ',' << "r_Quat_x" << ','
                                << "r_Quat_y" << ',' << "r_Quat_z" << ',' << "r_Accel_x" << ',' << "r_Accel_y" << ',' << "r_Accel_z"
                                << ',' << "r_Gyro_x" << ',' << "r_Gyro_y" << ',' << "r_Gyro_z"<< endl;

                        for (unsigned long long i = 0; i<r_data.size(); i++)
                        {
                            outFile << r_data[i].time << ',' << r_data[i].pressure[0] << ','
                                    << r_data[i].pressure[1] << ',' << r_data[i].pressure[2]
                                    << ',' << r_data[i].pressure[3] << ',' << r_data[i].pressure[4]
                                    << ',' << r_data[i].pressure[5] << ',' << r_data[i].pressure[6]
                                    << ',' << r_data[i].pressure[7] << ',' << r_data[i].pressure[8]
                                    << ',' << r_data[i].quat[0] << ',' << r_data[i].quat[1]
                                    << ',' << r_data[i].quat[2] << ',' << r_data[i].quat[3]
                                    << ',' << r_data[i].accel[0] << ',' << r_data[i].accel[1]
                                    << ',' << r_data[i].accel[2] << ',' << r_data[i].gyro[0]
                                    << ',' << r_data[i].gyro[1] << ',' << r_data[i].gyro[2] << endl;
                        }
                    }
                    r_csv.close();

        QDir dir(WorkFloder);
        //判断路径是否存在
        if(!dir.exists())
        {
            qDebug("mulubucunzai\n");
            return ;
        }
        dir.setFilter(QDir::Files); //实现对文件的过滤
        dir.setSorting(QDir::Name); //实现对文件输出的排序

        QFileInfoList list = dir.entryInfoList();
        QStringList string_list;

        for (int i = 0; i < list.size(); ++i)
        {
            QFileInfo fileInfo = list.at(i);
            QString suffix = fileInfo.suffix();
            if(QString::compare(suffix,QString("csv"),Qt::CaseInsensitive) ==  0)//通过QFileInfo来实现对文件类型的过滤
            {
                QString absolute_file_path = fileInfo.absoluteFilePath();
                string_list.append(absolute_file_path);
            }

        }
}
/************************************************************************************/

//是否添加建议
void uploadFile::addSuggestion()//添加建议
{
    qDebug()<<"添加建议";
}

void uploadFile::abolishSuggestion()//不添加建议
{
    qDebug()<<"不添加建议";
}

/*****************************************************************************************************/
//上传zip文件
int iType;      //第二次下载的限制条件

void uploadFile::uploadFiles(QString zipName)
    {
        iType=0;
        QFileInfo zipFile(zipName);//zipname是zip文件的路径
        if(!zipFile.exists())
        {
            return;
        }
        m_manager = new QNetworkAccessManager();
        QUrl url(baseUrl + uploadFilesApi);
        qDebug()<<"url:"<<url;
        QNetworkRequest request(url);
        qDebug()<<"上传zip文件时，提交token字符串："<<token;
        request.setRawHeader("Authorization",token.toUtf8());

        QHttpPart filePart;

        filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(QString("form-data; name=\"file\";filename=\"%1\"").arg(UploadZipName
                                                                                                                                       +".zip")));
        qDebug()<<"1";
        file = new QFile(zipName);
        file->open(QIODevice::ReadOnly);
        filePart.setBodyDevice(file);
        qDebug()<<"2";
        QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
        multiPart->append(filePart);
        file->setParent(multiPart);
        qDebug()<<"3";
        reply = m_manager->post(request, multiPart);
        connect(reply,&QNetworkReply::readyRead,this,&uploadFile::uploadReply);
//       emit startWait();
        loadingDialog = new LoadingDialog;
        loadingDialog->show();
       QEventLoop eventLoop;//事件计时
        connect(m_manager,SIGNAL(finished(QNetworkReply*)),&eventLoop,SLOT(quit()));
        eventLoop.exec();
        loadingDialog->close();
        delete loadingDialog;
//        emit stopWait();
        m_manager->deleteLater();
        m_manager = nullptr;
        file->close();
        file->deleteLater();
        file = nullptr;


    }

//上传回复（与请求下载(askdialog.cpp中的void AskDialog::loginResult())过程基本一样）
int serverFile;     //刷新文件的id
void uploadFile::uploadReply()//网络请求回复管理中的上传回复
    {
        qDebug()<<"网路请求的上传回复reply";
        QByteArray ba;
        while (!reply->atEnd())
        {
            ba = reply->readAll();
        }
        QJsonDocument document = QJsonDocument::fromJson(ba);
        QJsonObject replyObject = document.object();
        qDebug()<<"replyObject的值："<<replyObject;
        int status = replyObject.value("code").toInt();//更新
        qDebug()<<"replyObject中的code的值："<<status;

        if(status == 20000)
        {
            serverFile = replyObject.value("data").toObject().value("id").toInt();  //更新
            qDebug()<<"上传文件的id(serverFile的值)为："<<serverFile;

        } else {
            QString msg = replyObject.value("message").toString();
            qDebug()<< status;
            qDebug()<< msg;
            QString info = "上传失败:" + QString::number(status) + msg;
            qDebug()<< info;
            QMessageBox::about(NULL,"上传错误",info);
            reply->deleteLater();
            reply = nullptr;
            return;
        }
        reply->deleteLater();
        reply = nullptr;
        sleep(1);
        if(printContentChoose==1||printContentChoose==3||printContentChoose==NULL)
        {
      downloadPdf(downloadGaitPdfApi,"步态分析");//更新
        }
        else if(printContentChoose==2)
        {
            downloadPdf( downloadBalancePdfApi,"平衡测试");
            }
        //自加    因为这第一次下载还没有将所有数据download结束，这会使一些数据会被覆盖，因此要等第一次download结束后，再根据iType来进行第二次2下载
    }

//下载pdf文件
QFile *pdf;
void uploadFile::downloadPdf(QString Api,QString name)
    {
        pdf = new QFile();//创建到堆上，内存更大
        qDebug()<<"开始下载pdf";
        if(serverFile == 0)
        {
            QMessageBox::about(NULL,"下载错误","服务器端文件未找到");
            return;
        }

        //创建pdf
        QDateTime time = QDateTime::currentDateTime();   //获取当前时间
        QString timeT = time.toString("yyyyMMddhhmmss");
        QString pdfPathName = SaveFloder + "/" + UploadZipName+"-"+name+"-"+ timeT + ".pdf";     //pdf文件保存路径

        pdf->setFileName(pdfPathName);
        pdf->open(QIODevice::WriteOnly|QIODevice::Truncate);
        //通信
        QString a= QString::number(serverFile);
        QUrl url(baseUrl + Api + QString::number(serverFile));  //更新
        qDebug()<<"pdf文件所在的url位置："<<url;
        QNetworkRequest request(url);
        qDebug()<<"请求回复所携带的token为："<<token;//更新
        request.setRawHeader("Authorization",token.toUtf8());
        m_manager = new QNetworkAccessManager();
        reply = m_manager->get(request);//更新
        connect(reply,&QNetworkReply::readyRead,this,&uploadFile::downloadReply);
        connect(reply,&QNetworkReply::finished,this,&uploadFile::downloadFinish);  //下载成功

        QEventLoop loop;
        connect(m_manager,SIGNAL(finished(QNetworkReply*)),&loop,SLOT(quit()));//下载成功后，跳转退出
        loop.exec();
        m_manager->deleteLater();
        m_manager = nullptr;
        reply->deleteLater();
        reply = nullptr;
    }

//下载回复
void uploadFile::downloadReply()
{
    while (!reply->atEnd())
    {
        pdf->write(reply->readAll());
    }
}

//下载结束内容
void uploadFile::downloadFinish()
{
    if(reply->error() == QNetworkReply::NoError)
    {
        qDebug()<<"下载成功";
        pdf->close();        //新增
        QDesktopServices::openUrl(QUrl::fromLocalFile(pdf->fileName()));
        qDebug()<<"下载下来的pdf文件名以及位置为："<<pdf->fileName();//新增
        if(printContentChoose==3||printContentChoose==NULL)
        {
        openFile();//新增    开始第二个平衡测试报告的打印
        }
    }
    else {
        QMessageBox::about(NULL,"下载错误","服务器异常");
        pdf->close();
        return;
    }
}



//打开文件
void uploadFile::openFile()
{
    if(iType == 0){     //新增
        qDebug()<<"以下为平衡测试pdf的下载：";
        iType++;

        downloadPdf(downloadBalancePdfApi,"平衡测试");
    }
}
